#include "transit.h"

Transit::Transit(const int port):UDP(port)
{
}

Transit::~Transit()
{
	
}

int Transit::dealPackage(const unsigned char *package, const int packageSize, const struct sockaddr_in *rNetAddr)
{
	std::cout << __FUNCTION__ << ": recv package cmd is " << (int)(package[0]) << std::endl;
	ProtoCmd cmd = (ProtoCmd)package[0];
	switch (cmd)
	{
	case eLoginCmd:
		clientLogin(&package[1], packageSize - 1, rNetAddr);
		break;
	case eGetPeerNetAddrCmd:
		clientGetPeerNetAddr(&package[1], packageSize - 1, rNetAddr);
		break;
	default:
		std::cout << "unknow cmd ! cmd = " << cmd << std::endl;
		break;
	}

	return 0;
}

int Transit::clientLogin(const unsigned char *data, const int dataSize, const struct sockaddr_in *rNetAddr)
{
	int cpuIdSize = dataSize;
	if (cpuIdSize != CPU_ID_SIZE)
	{
		std::cout << "cpuIdSize error ! cpuIdSize = " << cpuIdSize << std::endl;
		return -3;
	}

	MacType macAddr;
	memcpy(macAddr, data, cpuIdSize);
	macAddr[cpuIdSize] = '\0';
	//std::string mac = std::string(macAddr);

	int ret = -1;
	if (_myMap.checkExist(macAddr) == false)
	{
		_myMap.insert(macAddr, rNetAddr);
		std::cout << "save new map data ! key = " << macAddr << ", value = " << inet_ntoa(rNetAddr->sin_addr) << ":" << ntohs(rNetAddr->sin_port) << std::endl;
		ret = 0;
	}
	else
	{
		std::cout << "macAddr is already in map ! macAddr = " << macAddr  << std::endl;
		ret = -2;
	}

	udpSendPackageData[0] = (unsigned char)eLoginCmd;
	udpSendPackageData[1] = (ret ? 1 : 0);
	int sendPackageSize = 2;

	sendUdpPackage(udpSendPackageData, sendPackageSize, listenSock, rNetAddr);
	return 0;
}

int Transit::clientGetPeerNetAddr(const unsigned char *data, const int dataSize, const struct sockaddr_in *rNetAddr)
{
	int cpuIdSize = dataSize;
	if (cpuIdSize != CPU_ID_SIZE)
	{
		std::cout << __FUNCTION__ << "cpuIdSize not right ! cpuIdSize = " << cpuIdSize << std::endl;
		return -1;
	}

	MacType macAddr;
	memcpy(macAddr, data, cpuIdSize);
	macAddr[cpuIdSize] = '\0';

	std::cout << __FUNCTION__ << ": macAddr is " << macAddr << std::endl;
	/*std::cout << __FUNCTION__ << ": macAddr is ";
	for (int i = 0; i < CPU_ID_SIZE; i++)
	{
		std::cout << i << ":" << std::hex << (int)macAddr[i] << std::endl;
	}
	std::cout << std::endl;*/

	int packageSize = 2;
	udpSendPackageData[0] = eGetPeerNetAddrCmd;

	if (_myMap.checkExist(macAddr) == false)
	{
		std::cout << "macAddr is not found in map ! macAddr = " << macAddr << std::endl;
		udpSendPackageData[1] = 1;
	}
	else
	{
		struct sockaddr_in peerNetAddr = _myMap.get(macAddr);
		udpSendPackageData[1] = 0;
		memcpy(&udpSendPackageData[2], &peerNetAddr, sizeof(struct sockaddr_in));
		packageSize = 2 + sizeof(struct sockaddr_in);
		std::cout << "get success ! peer net addr is " << inet_ntoa(peerNetAddr.sin_addr) << ":" << ntohs(peerNetAddr.sin_port) << std::endl;
	}

	sendUdpPackage(udpSendPackageData, packageSize, listenSock, rNetAddr);
	return 0;
}
